home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
comm
/
ns_16550.zip
/
PORT_ID.C
< prev
Wrap
Text File
|
1991-07-20
|
4KB
|
96 lines
/* port_id.c 1/18/89 Louis Shay
National Semiconductor Corporation
Microcomuputer Systems Division
Microcontroller Applications Group
Program to identify the presence and type of UART in a system.
This program will query the serial port at global port address
"int ubase", and return a value that identifies what type of UART
is present at that address. This address is set by the calling program
prior to the function call. The returned int values are:
0, if there is no identifiable UART at that port address.
1, if the port type is INS8250, INS8250-B.
2, if the port type is INS8250A, INS82C50A, NS16450, NS16C450.
3, if the port type is NS16550A.
4, if the port type is NS16C552.
note: the main source file should include "ns16550a.h". This is the
device header file.
*/
#include <stdio.h>
#include <conio.h>
#include "ns16550a.h"
int port_id()
{
extern int ubase; /* reference global address */
/* 1. test general functionality. Is the core register set present? */
wrLCR( 0xaa );
if( rdLCR() != 0xaa ) /* test LCR register & set DLAB=1 */
return( 0 );
/* as an identifier, UART address 1 is 8-bits (DLM) when LCR7=1 (DLAB).
UART address 1 is 4-bits (IER) when DLAB=0. */
wrDLM( 0x55 ); /* test for DLM present (8-bits) */
if( rdDLM() != 0x55 )
return( 0 );
wrLCR( 0x55 ); /* LCR: set DLAB = 0 */
if( rdLCR() != 0x55 )
return( 0 );
wrIER( 0x55 ); /* test for IER present (4-bits) */
if( rdIER() != 0x05 )
return( 0 );
wrFCR( 0 ); /* FIFOs off, if present */
wrIER( 0 ); /* interrupts off, IIR should be 01 */
if( rdIIR() != 1 )
return( 0 );
/* test modem control register address. Should be 5-bits wide */
wrMCR( 0xf5 ); /* 8-bit write */
if( rdMCR() != 0x15 ) /* expect 5-bit read */
return( 0 );
/* test MCR/MSR loopback functions */
wrMCR( 0x10 ); /* set loop mode */
(void)rdMSR(); /* clear out delta bits */
if( ( rdMSR() & 0xf0 ) != 0 ) /* check state bits */
return( 0 );
wrMCR( 0x1f ); /* toggle modem control lines */
if( ( rdMSR() & 0xf0 ) != 0xf0 ) /* check state bits */
return( 0 );
wrMCR( 0x03 ); /* exit loop mode, DTR, RTS active */
/* 2. port id successful at this point. determine port type */
wrSCR( 0x55 ); /* is there a scratch register? */
if( rdSCR() != 0x55 )
return( 1 ); /* no SCR, type = INS8250 */
wrFCR( 0xcf ); /* enable FIFO's, if present */
if( ( rdIIR() & 0xc0 ) != 0xc0 ) /* check FIFO ID bits */
return( 2 ); /* no FIFO's, type = NS16450 */
wrFCR( 0 ); /* turn off FIFO's */
wrLCR( 0x80 ); /* set DLAB */
wrAFR( 0x07 ); /* write to AFR */
if ( rdAFR() != 0x07 ) { /* read AFR */
wrLCR( 0x00 ); /* reset DLAB */
return ( 3 ); /* if not the same, type = NS16550A */
}
wrAFR( 0x00); /* clear AFR */
wrLCR( 0x00 ); /* reset DLAB */
return ( 4 ); /* type = NS16C552 */
}